#include "container.hpp"

using namespace Shiny;
using namespace Shiny::Widgets;

ProgressBar::ProgressBar() : Container(), _displayedPercentage(0), _percentage(0), _vertical(false), _side(false)
{
  _typeCode        = type2code<ProgressBar>::code;
}

void ProgressBar::SetProgressBarTexture(const sf::Texture* tex)
{
  if (tex)
    _progressBar.SetTexture(*tex);
}

void ProgressBar::UpdateProgressTexture(void)
{
  sf::IntRect        toPrint;
  const sf::Texture* texture = _progressBar.GetTexture();

  _displayedPercentage += (_displayedPercentage > _percentage ? -1.f : 1.f);
  _positionAdjust  = sf::Vector2f(0.f, 0.f);
  toPrint.Top      = 0.f;
  toPrint.Left     = 0.f;
  toPrint.Width    = texture->GetWidth();
  toPrint.Height   = texture->GetHeight();
  if (_vertical)
    toPrint.Height = toPrint.Height / 100 * _displayedPercentage;
  else
    toPrint.Width  = toPrint.Width  / 100 * _displayedPercentage;
  _progressBar.SetTextureRect(toPrint);
  if (_side)
  {
    if (_vertical)
      _positionAdjust.y = _drawableZone.Height - toPrint.Height;
    else
      _positionAdjust.x = _drawableZone.Width  - toPrint.Width;
  }
}

void ProgressBar::UpdateProgressShape(void)
{
  sf::Vector2f size;
  sf::IntRect  rect = BackgroundSprite().GetTextureRect();

  _displayedPercentage += (_displayedPercentage > _percentage ? -1.f : 1.f);
  _positionAdjust = sf::Vector2f(0.f, 0.f);
  size.x          = GetWidth();
  size.y          = GetHeight();
  if (_vertical)
    size.y        = size.y / 100 * _displayedPercentage;
  else
    size.x        = size.x / 100 * _displayedPercentage;
  _shape.SetSize(size);
  if (_side)
  {
    if (_vertical)
      _positionAdjust.y = _drawableZone.Height - size.y;
    else
      _positionAdjust.x = _drawableZone.Width  - size.x;
  }
}

void ProgressBar::SetPercentage(float v)
{
  _displayedPercentage = _percentage;
  if (v > 100) v       = 100.f;
  if (v < 0  ) v       = 0.f;
  _percentage          = v;
}

void ProgressBar::SetColor(const sf::Color color)
{
  _shape.SetFillColor(color);
}

void ProgressBar::SetSide(bool vertical, bool side)
{
  _vertical = vertical;
  _side     = side;
}

void ProgressBar::RenderSelf(void)
{
  Container::RenderSelf();
  if (_progressBar.GetTexture())
  {
    if (_percentage != _displayedPercentage) UpdateProgressTexture();
    _progressBar.SetPosition(_drawableZone.Left + _positionAdjust.x, _drawableZone.Top + _positionAdjust.y);
    Draw(_progressBar);
  }
  else
  {
    if (_percentage != _displayedPercentage) UpdateProgressShape();
    _shape.SetPosition(_drawableZone.Left + _positionAdjust.x, _drawableZone.Top + _positionAdjust.y);
    Draw(_shape);
  }
}
